﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Threading;
using System.Windows.Forms;
using KWindow.KCommon;
using System.Threading.Tasks;
using KWindow.KBase;
using KInterfaces;
using LogLib;
using System.Runtime.InteropServices;
using ComLib.ComType;
using KWindow.KControl;
using Mp3Player;

namespace KWindow.KPageCore
{
    public partial class PageControlBase : UserControl
    {
        #region static Fields and Functions    
        public static readonly string KeyboardManager = "SoftKeyBoardManager";

        public static readonly string KeyboardClass = "KeyboardManager.FormManager";
        static PageControlBase()
        {           
            CreatSpeaker();
        }

        public static void CloseKeyBoardManager(IntPtr hWnd)
        {
            KeyBoardArgs arg = new KeyBoardArgs();
            arg.SenderName = "";
            arg.PassageType = SendMessageType.Exit;
            arg.SenderHandle = hWnd;
            arg.MsgReceiver = hWnd;
            string parm = JsonHandler.ConvertToJsonString(arg).Replace('"', '@');
            SendMessageToKB(hWnd, parm);
        }

        protected static void SendMessageToKB(IntPtr windowHandle, string strMessage)
        {
            IntPtr hWnd = GetKeyBoardManagerMainWnd();
            if (hWnd == IntPtr.Zero)
            {
                MessageBox.Show("未能启动指定键盘!");
                return;
            }
            byte[] data = System.Text.Encoding.UTF8.GetBytes(strMessage);
            COPYDATASTRUCT_INTPTR cds = new COPYDATASTRUCT_INTPTR();
            cds.cbData = data.Length;
            cds.dwData = windowHandle;
            cds.lpData = Marshal.AllocHGlobal(data.Length);
            Marshal.Copy(data, 0, cds.lpData, data.Length);
            int nRet = Windows.SendMessage(hWnd, (int)KWindow.KCommon.MessageType.WM_COPYDATA, 0, ref cds);
            cds.Free();
        }

        protected static IntPtr GetKeyBoardManagerMainWnd()
        {
            IntPtr[] FindWindows = SearchWindow.Search(KeyboardManager, KeyboardClass);
            if (FindWindows.Length > 0)
            {
                return FindWindows[0];
            }
            return IntPtr.Zero;
        }
        #endregion
    
        protected Dictionary<string, bool> HasInputted = new Dictionary<string, bool>();
        protected Dictionary<string, KeyBoardArgs> TextBoxBindings = null;
        protected TextBox ActivedControl = null;
        protected Label labelTitle = null;
        protected List<Button> BaseButtons = null;
        protected List<Button> Buttons = null;
        protected List<Label> Labels = null;
        protected List<PictureBox> PictureBoxs = null;
        protected List<TextBox> TextBoxs = null;
        protected List<Image> Images = null;
        protected List<Panel> Panels = null;
        protected List<KCheckBox> CheckBoxs = null;
        protected List<XmlGroupObject> Groups = null;

        protected Button buttonNext = null;
        protected Button buttonLast = null;
        protected Button buttonHome = null;
        protected CountdownControl countdownControl1 = null;
        public string LanguageCode = "";
        protected bool _voiceEnabled = false;
        protected string _voiceFileName = "";
        protected int _countdownSecond = 0;
        protected bool _bInited = false;
        protected bool _countdownEnabled = false;
        public bool CountdownEnabled
        {
            get { return _countdownEnabled; }
        }

       
        public bool ContainsGroup
        {
            private set;
            get;
        }

        protected TextMapService textMapService = null;

        #region Keyboard Control
        protected void SetHasInputted(string key)
        {
            if (!HasInputted.ContainsKey(key))
            {
                HasInputted.Add(key, true);
            }
            else
            {
                HasInputted[key] = true;
            }
        }

        protected void textBoxInputting_Enter(object sender, EventArgs e)
        {
            if (!_bInited)
            {
                return;
            }
            ActivedControl = sender as TextBox;
            SetHasInputted(ActivedControl.Name);
            ShowSoftKeyBoard(ActivedControl);
        }

        protected void ShowSoftKeyBoard(TextBox tb)
        {
            if (TextBoxBindings == null)
                return;
            string name = tb.Name;
            if (!TextBoxBindings.ContainsKey(name))
            {
                return;
            }
            KeyBoardArgs arg = TextBoxBindings[name];
            arg.SenderName = name;
            arg.PassageType = SendMessageType.Request;
            arg.SenderHandle = this.Handle;
            arg.MsgReceiver = this.Handle;
            arg.Content = tb.Text;
            //播放语音
            if (!string.IsNullOrEmpty(TextBoxBindings[name].VoiceFileName)
                && File.Exists(TextBoxBindings[name].VoiceFileName))
            {
                Speak(TextBoxBindings[name].VoiceFileName);
            }
            string parm = JsonHandler.ConvertToJsonString(arg).Replace('"', '@');
            SendMessageToKB(this.Handle, parm);          
        }    

        protected void OnKeyBoardMsgReceived(System.Windows.Forms.Message m)
        {
            COPYDATASTRUCT_INTPTR cds = new COPYDATASTRUCT_INTPTR();
            Type mytype = cds.GetType();
            cds = (COPYDATASTRUCT_INTPTR)m.GetLParam(mytype);
            KeyBoardArgs arg = null;
            uint flag = (uint)(cds.dwData);
            byte[] data = new byte[cds.cbData];
            Marshal.Copy(cds.lpData, data, 0, data.Length);
            string jsonString = System.Text.Encoding.UTF8.GetString(data);
            try
            {
                arg = JsonHandler.ConvertToJsonObject<KeyBoardArgs>(jsonString);
            }
            catch (Exception ex)
            {
                string errInfo = string.Format("无法解析的string: \n\t{0}", jsonString);
                MessageBox.Show(errInfo, ex.Message);
                Log.Write(ex.ToString());
                return;
            }         
            if (!string.IsNullOrEmpty(arg.Command) && arg.Command.Equals("Cancel"))
            {
                Log.Write("用户取消了输入.");
                return;
            }
            string key = TextBoxBindings.FirstOrDefault(q => q.Value.Key.Equals(arg.Key)).Key;  //get first key
            TextBox tb = TextBoxs.Find(r => r.Name.Equals(key));
            if (tb == null)
            {
                return;
            }

            // 更新字典关键字代码的映射
            if (!string.IsNullOrEmpty(arg.DictionaryFileName))
            {
                textMapService[arg.Key] = arg.Code;
            }

            if (arg.DictionaryFileName.StartsWith("Date"))
            {
                DateTime dt = DateTime.Parse(arg.Content);
                tb.Text = dt.ToString("yyyyMMdd");
            }
            else if (arg.DictionaryFileName.Equals("Citys"))
            {
                tb.Text = arg.FullContent;
            }
            else
            {
                tb.Text = arg.Content;
            }

            Task.Factory.StartNew(() => 
            {
                Thread.Sleep(1000);
                CheckFillingIsCompleted();
            });           
        }

        protected override void DefWndProc(ref System.Windows.Forms.Message m)
        {
            switch (m.Msg)
            {
                case (int)MessageType.WM_COPYDATA:
                    OnKeyBoardMsgReceived(m);
                    break;
                default:
                    base.DefWndProc(ref m);
                    break;
            }
        }

        protected void CheckFillingIsCompleted()
        {
            if (this.InvokeRequired)
            {
                Action outdelegate = new Action(CheckFillingIsCompleted);
                this.Invoke(outdelegate, new object[] { });
                return;
            }
            foreach (TextBox tb in TextBoxs)
            {
                if (!tb.Enabled)
                {
                    continue;
                }
                if (!TextBoxBindings.ContainsKey(tb.Name))
                {
                    continue;
                }
                if (!string.IsNullOrEmpty(tb.Text))
                {
                    continue;
                }
                KeyBoardArgs args = TextBoxBindings[tb.Name];
                if (args.NotNull)
                {
                    tb.Focus();
                    return;           
                }
                else
                {
                    continue;
                }
            }       
        }

        #endregion

        #region Design Custom Controls
        //public string XmlConfigFolder = "";
        /// <summary> 
        /// 设计器支持所需的方法: 执行创建自定义控件以及控件布局
        /// </summary>
        protected void InitializeCustomComponent<T>(T parent) where T : PageControlBase
        {
            _config = PageConfigService.Instance;
            string directory = AssemblyDirectory;
            StaticTypes.SetRootDirectory(directory);
            string XmlConfigFolder = string.Format(@"{0}\UI\", directory);
            string XmlConfigFile = string.Format(@"{0}{1}.xml", XmlConfigFolder, parent.GetType().Name);
            if (!File.Exists(XmlConfigFile))
            {
                return;
            }
            SetStyles();
            XmlUIObject<T> UIConfig = new XmlUIObject<T>(parent, XmlConfigFile);
            UIConfig.OnParsing();
            ContainsGroup = UIConfig.ContainsGroup;

            Panels = UIConfig.CreatPanels();
            BaseButtons = UIConfig.CreatBaseButtons();
            Buttons = UIConfig.CreatButtons();
            TextBoxs = UIConfig.CreatTextBoxs();
            Labels = UIConfig.CreatLabels();
            PictureBoxs = UIConfig.CreatPictureBoxs();
            TextBoxBindings = UIConfig.InputtingBindings;
            Images = UIConfig.LoadImages();
            countdownControl1 = UIConfig.CreatCountdownControl();
            if(ContainsGroup)
            {
                Groups = UIConfig.Groups;
                CheckBoxs = UIConfig.CreatKCheckBoxs();
            }
            
            parent.SuspendLayout();

            if(TextBoxs != null && TextBoxs.Count > 0)
            {
                textMapService = new TextMapService(TextBoxs, TextBoxBindings);
            }           

            foreach (Panel panel in Panels)
            {
                parent.Controls.Add(panel);
            }
           
            foreach (Label lab in Labels)
            {
                parent.Controls.Add(lab);
            }

            foreach (TextBox tb in TextBoxs)
            {
                parent.Controls.Add(tb);
            }

            foreach (Button btn in BaseButtons)
            {
                parent.Controls.Add(btn);
            }

            foreach (Button btn in Buttons)
            {
                parent.Controls.Add(btn);
            }

            foreach (PictureBox pic in PictureBoxs)
            {
                parent.Controls.Add(pic);
            }

            if (ContainsGroup)
            {
                foreach (KCheckBox cbox in CheckBoxs)
                {
                    parent.Controls.Add(cbox);
                }
            }

            foreach (Control ctl in UIConfig.Controls)
            {
                parent.Controls.SetChildIndex(ctl, 0);
            }

            foreach (PictureBox pic in PictureBoxs)
            {
                ((System.ComponentModel.ISupportInitialize)(pic)).EndInit();
            }
            parent.Controls.Add(countdownControl1);

            XmlFormObject formConfigs = UIConfig.MainFormConfig;
            formConfigs.SetValues(parent);          
            parent.ResumeLayout(false);
            parent.PerformLayout();
            _voiceEnabled = formConfigs.VoiceEnabled;
            _voiceFileName = formConfigs.VoiceFileName;
            _countdownEnabled = UIConfig.CountdownConfigs.Enabled;
            _countdownSecond = UIConfig.CountdownConfigs.CountDownSecond;
            InitCtrls();
        }

        /// <summary> 
        /// 设计器支持所需的方法: 执行创建自定义控件以及控件布局
        /// </summary>
        protected void RefreshCustomComponent<T>(T parent) where T : PageControlBase
        {
            string directory = AssemblyDirectory;
            StaticTypes.SetRootDirectory(directory);
            string XmlConfigFolder = string.Format(@"{0}\UI\", directory);
            string XmlConfigFile = string.Format(@"{0}{1}.xml", XmlConfigFolder, parent.GetType().Name);
            if (!File.Exists(XmlConfigFile))
            {
                return;
            }          
            XmlUIObject<T> UIConfig = new XmlUIObject<T>(parent, XmlConfigFile);
            UIConfig.OnParsing();
            ContainsGroup = UIConfig.ContainsGroup;
            UIConfig.ApplyPanels(Panels);
            UIConfig.ApplyBaseButtons(BaseButtons);
            UIConfig.ApplyButtons(Buttons);
            UIConfig.ApplyLabels(Labels);
            UIConfig.ApplyPictureBoxs(PictureBoxs);
            UIConfig.ApplyTextBoxs(TextBoxs);
            if(ContainsGroup)
            {
                UIConfig.ApplyKCheckBoxs(CheckBoxs);
            }
            UIConfig.ApplyCountdownControl(countdownControl1);
            TextBoxBindings = UIConfig.InputtingBindings;        
            Images = UIConfig.LoadImages();
            textMapService.UpdateData(TextBoxs, TextBoxBindings);
            XmlFormObject formConfigs = UIConfig.MainFormConfig;
            formConfigs.SetValues(parent);
            _countdownEnabled = UIConfig.CountdownConfigs.Enabled;
            _countdownSecond = UIConfig.CountdownConfigs.CountDownSecond;
            InitCtrls();
        }

        protected Image GetImage(string name)
        {
            return Images.Find(r=>((string)(r.Tag)).Equals(name));
        }

        protected Control GetControl<T>(string name)
        {
            Type type = typeof(T);
            foreach (Control ctl in Controls)
            {
                if (ctl.GetType() == type)
                {
                    if (ctl.Name.Equals(name))
                    {
                        return ctl;
                    }
                }
            }
            return null;
        }

        protected void LoadImages()
        {

        }

        #endregion

        #region Group Controls Command
        ///////////////////////////////////////////////////////////////////////////////////
        // 组控件的显示逻辑：同一组内的控件同时只能一个被选中，类似于单选框
        // 组名唯一，组的父控件唯一，
        // 同一个组只能有一个父控件，
        // 同一个控件不能作为两个组的父控件
        ///////////////////////////////////////////////////////////////////////////////////
             
        /// <summary>
        /// 当前所有选中的控件集合
        /// </summary>
        protected List<Control> listCheckedControls = new List<Control>();

        //protected XmlGroupObject SelectedGroup;

        /// <summary>
        /// 组从属关系最大层级数
        /// </summary>
        ///protected int MaxLevel = 0;

        /// <summary>
        /// 根组控件集合(第一级别)
        /// </summary>
        protected Dictionary<string, List<Control>> dicRootGroup= new Dictionary<string, List<Control>>();

        /// <summary>
        /// 从组控件集合(不属于第一级别的从属组合)
        /// </summary>
        protected Dictionary<Control, List<Control>> dicSubGroup = new Dictionary<Control, List<Control>>();

        /// <summary>
        /// 存储所有控件所在组的级别
        /// </summary>
        protected Dictionary<Control, int> dicGroupLevel = new Dictionary<Control, int>();

        /// <summary>
        /// 不同组的父控件可能同时控制一些共享组件
        /// </summary>
        protected List<Control> listSharedGroup = new List<Control>();

        protected void SetDefaultControlCheckedInGroup(string groupName)
        {
            if(Groups != null)
            {
                int index = Groups.FindIndex(r => r.Name.Equals(groupName));
                if (index >= 0)
                {
                    string controlName = Groups[index].Default;
                    if (CheckBoxs != null && CheckBoxs.Count > 0)
                    {
                        int indexCheckBox = CheckBoxs.FindIndex(r => r.Name == controlName);
                        if (indexCheckBox >= 0)
                        {
                            CheckBoxs[indexCheckBox].Checked = true;
                        }
                    }                       
                }
            }          
        }

        protected List<XmlGroupMemberObject> GetXmlGroupMembers(string parent)
        {
            int index = Groups.FindIndex(r=>r.Parent.Equals(parent));
            if(index < 0)
            {
                throw new Exception("未知的父控件：" + parent);
            }
            XmlGroupObject group = Groups.Find(r => r.Parent.Equals(parent));
            return group.Controls;
        }

        /// <summary>
        /// 初始化组控件集合
        /// </summary>
        /// <returns></returns>
        protected void InitGroupCtrls()
        {
            dicRootGroup.Clear();
            dicSubGroup.Clear();
            dicGroupLevel.Clear();
            listSharedGroup.Clear();
            for (int i = 0; i < Groups.Count; i++)
            {
                string parentName = Groups[i].Parent;               
                List<XmlGroupMemberObject> listMembers = Groups[i].Controls;
             
                // 首先识别共享组件集合
                if(parentName.Equals("Share"))
                {
                    foreach (XmlGroupMemberObject member in listMembers)
                    {
                        Control child = Controls[member.Name];
                        if (child == null)
                        {
                            throw new Exception("根组成员中包含未知的控件, 名称为:" + member.Name);
                        }
                        listSharedGroup.Add(child);                   
                    }
                    continue;
                }
                if((listMembers == null || listMembers .Count == 0) && Groups[i].Depth > 0)
                {
                    Control parentControl = Controls[parentName];
                    if (parentControl == null)
                    {
                        throw new Exception("窗体中包含未知的父节点控件, 名称为:" + Groups[i].Name);
                    }
                    dicSubGroup.Add(parentControl, null);
                    if (!dicGroupLevel.ContainsKey(parentControl))
                    {
                        dicGroupLevel.Add(parentControl, Groups[i].Depth);
                    }
                    else
                    {
                        int nv = dicGroupLevel[parentControl];
                        dicGroupLevel[parentControl] = (Groups[i].Depth < nv ? Groups[i].Depth : nv);
                    }
                    continue;
                }
                //if (string.IsNullOrEmpty(parentName))
                //{
                //    throw new Exception("组的从属父节点为空, 组名称为:" + Groups[i].GroupName);
                //}
                // 根组
                if (Groups[i].Depth == 0 || parentName.Equals("root"))
                {
                    List<Control> listChilds = new List<Control>();
                    foreach (XmlGroupMemberObject member in listMembers)
                    {
                        Control child = Controls[member.Name];
                        if (child == null)
                        {
                            throw new Exception("根组成员中包含未知的控件, 名称为:" + member.Name);
                        }
                        listChilds.Add(child);
                        if (!dicGroupLevel.ContainsKey(child))
                        {
                            dicGroupLevel.Add(child, member.Level);
                        }
                        else
                        {
                            dicGroupLevel[child] = (member.Level < dicGroupLevel[child] ? member.Level : dicGroupLevel[child]);            
                        }
                    }
                    dicRootGroup.Add(Groups[i].Name, listChilds);
                    continue;
                }
                else if(Groups[i].Depth > 0)
                {
                    Control parentControl = Controls[parentName];
                    if (parentControl == null)
                    {
                        throw new Exception("窗体中包含未知的父节点控件, 名称为:" + Groups[i].Name);
                    }                  
                    List<Control> listChilds = new List<Control>();
                    foreach (XmlGroupMemberObject member in listMembers)
                    {
                        Control child = Controls[member.Name];
                        if (child == null)
                        {
                            throw new Exception("组成员中包含未知的控件, 名称为:" + member.Name);
                        }
                        listChilds.Add(child);
                        if (!dicGroupLevel.ContainsKey(child))
                        {
                            dicGroupLevel.Add(child, member.Level);
                        }
                        else
                        {
                            dicGroupLevel[child] = (member.Level < dicGroupLevel[child] ? member.Level : dicGroupLevel[child]);
                        }
                    }
                    dicSubGroup.Add(parentControl, listChilds);
                    continue;
                }              
            }
        }

        private void ShowRootGroupCtrls()
        {
            foreach(List<Control> list in dicRootGroup.Values)
            {
                list.ForEach(r => r.Visible = true);
            }
            foreach (List<Control> list in dicSubGroup.Values)
            {
                if(list != null)
                {
                    list.ForEach(r => r.Visible = false);
                }               
            }
        }

        protected bool IsRootGroupControl(Control ctl)
        {
            foreach(List<Control> list in dicRootGroup.Values)
            {
                if(list.Contains(ctl))
                {
                    return true;
                }
            }
            return false;
        }

        /// <summary>
        /// 找到位于同一组的其它控件
        /// </summary>
        /// <param name="ctl">当前选中的控件</param>
        /// <returns></returns>
        protected List<Control> GetGroupBrotherControl(Control ctl)
        {
            if(!dicGroupLevel.ContainsKey(ctl))
            {
                throw new Exception("级数字典中包含未知的控件, 名称为:" + ctl.Name);
            }
            List<Control> listBrothers = new List<Control>();
           
            // 从根控件组查找
            if (dicGroupLevel[ctl] == 0 && IsRootGroupControl(ctl))
            {
                foreach(List<Control> list in dicRootGroup.Values)
                {
                    if(list.Contains(ctl))
                    {
                        listBrothers.AddRange(list);
                        listBrothers.Remove(ctl);
                        return listBrothers;
                    }
                }
                return listBrothers;
            }

            // 从非根组中查找
            foreach (KeyValuePair<Control, List<Control>> pair in dicSubGroup)
            {
                Control key = pair.Key;
                List<Control> list = pair.Value;
                if(list == null)
                {
                    continue;
                }
                if (listCheckedControls.Contains(key) && list.Contains(ctl))
                {
                    listBrothers.AddRange(list);
                    listBrothers.Remove(ctl);
                    return listBrothers;
                }
            }
            return listBrothers;
        }

        protected virtual void CheckBox_CheckedChanged(object sender, EventArgs e)
        {
            if (sender is KCheckBox)
            {
                KCheckBox box = sender as KCheckBox;
                if(box.Checked)
                {
                    OnCheckBoxChecked(box);
                }
                else
                {
                    OnCheckBoxUnChecked(box);
                }
            }
        }

        protected void CheckOtherShareCheckBox(Control control)
        {
            if (!listSharedGroup.Contains(control))
            {
                return;
            }
            foreach (Control sharedControl in listSharedGroup)
            {
                if (sharedControl == control)
                {
                    continue;
                }
                if (sharedControl is KCheckBox)
                {
                    KCheckBox box = sharedControl as KCheckBox;
                    if (box.Checked)
                    {
                        OnCheckBoxChecked(sharedControl);
                    }
                }
            }
        }

        protected void OnCheckBoxChecked(Control control)
        {
            if(!listCheckedControls.Contains(control))
            {
                listCheckedControls.Add(control);
            }              
            SetBrotherControlCheckedStatus(control);
            if (dicSubGroup.ContainsKey(control))
            {
                SetGroupMemberValue(control, true);
            }          
        }

        protected void OnCheckBoxUnChecked(Control control)
        {
            if (listCheckedControls.Contains(control))
            {
                listCheckedControls.Remove(control);
            }
            if (dicSubGroup.ContainsKey(control))
            {
                SetGroupMemberValue(control, false);
            }

            // 假如是共享组件, 需要处理设置其他共享组件的状态
            if (listSharedGroup.Contains(control))
            {
                CheckOtherShareCheckBox(control);
            }
        }

        protected void SetBrotherControlCheckedStatus(Control control)
        {
            List<Control> listBrothers = GetGroupBrotherControl(control);
            for(int i = 0; i < listBrothers.Count; i++)
            {
                Control brother = listBrothers[i];
                if(brother is KCheckBox)
                {
                    KCheckBox box = brother as KCheckBox;
                    box.Checked = false;
                }
            }
        }

        /// <summary>
        /// 设置组内成员控件的值
        /// 如果组当前为选中状态，则设置默认成员为选中
        /// 如果组当前为未选中状态，则设置所有成员为未选中（同时对用户隐藏）
        /// </summary>
        /// <param name="parentControl">组的父控件</param>
        /// <param name="groupChecked">组当前是否被选中</param>
        protected void SetGroupMemberValue(Control parentControl, bool groupChecked)
        {
            List<Control> listMembers = dicSubGroup[parentControl];
            XmlGroupObject group = Groups.Find(r => r.Parent.Equals(parentControl.Name));
            List<XmlGroupMemberObject> listConfig = GetXmlGroupMembers(parentControl.Name);
            if (string.IsNullOrEmpty(group.Name))
            {
                throw new Exception("配置中未找到指定组, 其父控件名称为:" + parentControl.Name);
            }
            if (listMembers == null)
            {
                return;
            }
            for (int i = 0; i < listMembers.Count; i++)
            {
                Control child = listMembers[i];
                child.Visible = groupChecked;
                XmlGroupMemberObject config = listConfig.Find(r => r.Name.Equals(child.Name));
                if(string.IsNullOrEmpty(config.Name))
                {
                    throw new Exception("组配置中未找到指定控件, 名称为:" + child.Name);
                }
                if (groupChecked)
                {
                    config.SetControlValue(child);                   
                }
                if (child is KCheckBox)
                {
                    KCheckBox cb = child as KCheckBox;                  
                    if (cb.Name.Equals(group.Default) && groupChecked)
                    {
                        cb.Checked = true;
                    }
                    else
                    {
                        cb.Checked = false;
                    }
                    cb.Visible = groupChecked;
                }
            }         
        }
        #endregion

        #region Speaker
        /// <summary>
        /// 语音播放执行者
        /// </summary>
        protected static Speaker _speaker = null;

        public static void CreatSpeaker()
        {
            _speaker = new Speaker();
        }

        public void Speak(string info)
        {
            if (this.InvokeRequired)
            {
                Action<string> outdelegate = new Action<string>(Speak);
                this.BeginInvoke(outdelegate, new object[] { info });
                return;
            }
            _speaker.VoiceDirectory = AssemblyDirectory;
            _speaker.Add(info);
        }

        public void Speak(List<string> infos)
        {
            if (this.InvokeRequired)
            {
                Action<List<string>> outdelegate = new Action<List<string>>(Speak);
                this.BeginInvoke(outdelegate, new object[] { infos });
                return;
            }
            _speaker.VoiceDirectory = AssemblyDirectory;
            _speaker.AddList(infos);
        }
        #endregion

        protected const int PhotosCount = 2;

        public IPageProcess Process
        {
            get;
            protected set;
        }

        public ShareData SD
        {
            get 
            {
                if (Process != null)
                {
                    return Process.SD;
                }
                return null;
            }
        }

        protected PageConfigService _config = null;

        public virtual string AppName
        {
            get
            {
                return "";
            }
        }

        public virtual string AssemblyDirectory
        {
            get
            {
                return "";
            }
        }

        public PageControlBase()
        {         
            InitializeComponent();
        }

        public void SetStyles()
        {
            this.DoubleBuffered = true;//设置本窗体
            SetStyle(ControlStyles.UserPaint, true);
            SetStyle(ControlStyles.AllPaintingInWmPaint, true); // 禁止擦除背景.
            SetStyle(ControlStyles.DoubleBuffer, true); // 双缓冲
        }

        public void SetButtonDefaultStyles(Button btn)
        {
            btn.BackColor = Color.Transparent;
            btn.FlatStyle = FlatStyle.Flat;
            btn.FlatAppearance.BorderSize = 0;
            btn.FlatAppearance.MouseDownBackColor = Color.Transparent;
            btn.FlatAppearance.MouseOverBackColor = Color.Transparent;
            btn.FlatAppearance.BorderSize = 0;           
        }
  
        /// <summary>
        /// 开启窗体业务后即调用
        /// </summary>
        public void PlayWelcomeVoice()
        {
            if (_voiceEnabled)
            {
                _speaker.VoiceDirectory = AssemblyDirectory;
                _speaker.OnSpeaking(_voiceFileName);        
            }            
        }

        /// <summary>
        /// 应用语言
        /// </summary>
        /// <param name="code"></param>
        public virtual void ApplyLanguage(string code)
        {
            LanguageCode = code;
        }

        //初始化窗体控件(创建后只调用一次)
        protected virtual void InitCtrls()
        {
            Control c0 = GetControl<Button>("buttonHome");
            if (c0 != null)
            {
                buttonHome = c0 as Button;
            }

            Control c1 = GetControl<Button>("buttonNext");
            if (c1 != null)
            {
                buttonNext = c1 as Button;
            }

            Control c2 = GetControl<Button>("buttonLast");
            if (c2 != null)
            {
                buttonLast = c2 as Button;
            }     

            Control c3 = GetControl<Label>("labelTitle");
            if (c3 != null)
            {
                labelTitle = c3 as Label;
            }
            countdownControl1.Visible = _countdownEnabled;
            if(ContainsGroup)
            {
                try
                {
                    InitGroupCtrls();
                    ShowRootGroupCtrls();
                    foreach (KCheckBox cbox in CheckBoxs)
                    {
                        cbox.CheckedChanged += CheckBox_CheckedChanged;
                    }                  
                }
                catch (Exception ex)
                {
                    string errInfo = "InitGroupCtrls发生了异常";
                    MessageBox.Show(errInfo, ex.Message);
                    Log.WriteException(ex.ToString());
                }             
            }
        }

        /// <summary>
        /// 处理问候音播报完成后的事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public virtual void SpeakingDone(object sender, QueueSpeakingDoneEventArgs e)
        {
            //添加其他开始处理的代码

        }

        protected virtual void btnBack_Click(object sender, EventArgs e)
        {
            ClearData();
            Process.ToLast();
        }

        protected virtual void btnNext_Click(object sender, EventArgs e)
        {
            StopCountdown();
            UpdateData();
            Process.ToNext();
        }

        protected virtual void btnHome_Click(object sender, EventArgs e)
        {
            ClearData();
            Process.ToHome();
        }

        //初始化窗体数据
        public virtual void InitData()
        {

        }

        /// <summary>
        /// 保存窗体数据(窗体本次做完后, 进入下一步之前)
        /// </summary>
        public virtual void UpdateData()
        {

        }

        /// <summary>
        /// 清理窗体数据(窗体本次做完后)
        /// </summary>
        public virtual void ClearData()
        {
            countdownControl1.Stop();
            if (textMapService != null)
            {
                textMapService.ClearData();
            }        
            if(TextBoxs != null)
            {
                for (int i = 0; i < TextBoxs.Count; i++)
                {
                    TextBoxs[i].Text = "";
                }
            }
            _bInited = false;
        }
      
        /// <summary>
        /// 窗体关闭时
        /// </summary>
        public virtual void Close()
        {
            if (_countdownEnabled || countdownControl1.IsRunning)
            {
                countdownControl1.CloseCountDown();
            }
        }

        public virtual void StartWork()
        {

        }

        public virtual void StopWork()
        {

        }

        public virtual void AbortWork()
        {

        }

        // Countdown
        public virtual void StartCountdown()
        {
            countdownControl1.Restart(_countdownSecond, OnCountdownCompleted);
        }

        public virtual void SuspendCountdown()
        {
            countdownControl1.Start(OnCountdownCompleted);
        }

        public virtual void StopCountdown()
        {
            if(countdownControl1.IsRunning)
            {
                countdownControl1.Stop();
            }            
        }

        public virtual void OnCountdownCompleted(object sender, EventArgs e)
        {
            AbortWork();
            ClearData();
            Process.ToHome();
        }
    }
}
